using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Globalization;
using System.Text.RegularExpressions;

namespace Rocket.Core.Common
{
    /// <summary>
    /// Contains all constant strings used in the system 
    /// including keys of the web.config.
    /// </summary>
    public class DataManager
    {
        #region Public Methods

        #region Null Handlers
        #region LeadingZero

        /// <summary>
        /// Get Leading Zero(s) for given number of digit
        /// </summary>
        /// <param name="number">Number</param>
        /// <param name="noOfDigits">No Of Digits</param>
        /// <returns>String with appropriate leading zeros</returns>
        public static string LeadingZero(int number, int noOfDigits)
        {
            double tempNo;
            string tempString;

            tempNo = number / Math.Pow(10, (double)noOfDigits);

            tempString = tempNo.ToString();
            if (tempString == "0.1") tempString = "0.10";
            return tempString.Substring(tempString.IndexOf('.') + 1, noOfDigits);
        }

        #endregion

        #region DateTime SetMinimumdate()
        public static DateTime SetMinimumdate()
        {
            return new DateTime(1900, 1, 1, 0, 0, 0);
        }
        #endregion

        #region object ValueOF(string Value)
        public static object ValueOF(string Value)
        {
            if (Value == "" || Value == null)
            {
                return DBNull.Value;
            }
            else
            {
                return Value.TrimEnd();
            }
        }
        #endregion

        #region object ValueOF(bool Value)
        public static object ValueOF(bool Value)
        {
            if (Value.Equals(null))
            {
                return false;
            }
            else
            {
                return Value;
            }
        }
        #endregion

        #region object ValueOF(int Value)
        public static object ValueOF(int Value)
        {
            if (Value.Equals(null))
            {
                return DBNull.Value;
            }
            else
            {
                return Value;
            }
        }
        #endregion

        #region object ValueOF(int? Value)
        public static object ValueOF(int? Value)
        {
            if (Value.Equals(null))
            {
                return DBNull.Value;
            }
            else
            {
                return Value;
            }
        }
        #endregion

        #region object ValueOF(double Value)
        public static object ValueOF(double Value)
        {
            if (Value.Equals(null))
            {
                return DBNull.Value;
            }
            else
            {
                return Value;
            }
        }
        #endregion

        #region object ValueOF(DateTime? Value)
        public static object ValueOF(DateTime? Value)
        {
            if (Value.Equals(null))
            {
                return DBNull.Value;
            }
            else
            {
                return Value;
            }
        }
        #endregion

        #region object AvoidNull(object Value)
        public static object AvoidNull(object Value)
        {
            if (Value == DBNull.Value) return null;
            else return Value;
        }
        #endregion

        #region string AvoidNullStr(object Value)
        /// <summary>
        /// Convert and trim string databse object
        /// </summary>
        /// <param name="Value"></param>
        /// <returns>string value</returns>
        public static string AvoidNullStr(object Value)
        {
            if ((Value == null) || (Value == DBNull.Value)) return String.Empty;
            else return ((string)Value).Trim();
        }
        #endregion

        #region char AvoidNullChar(object Value)
        /// <summary>
        /// Convert and char database object
        /// </summary>
        /// <param name="Value"></param>
        /// <returns>char value</returns>
        public static char AvoidNullChar(object Value)
        {
            if ((Value == null) || (Value == DBNull.Value)) return Char.MinValue;
            else return ((char)Value);
        }
        #endregion

        #region object AvoidNullByteArray(object Value)
        public static object AvoidNullByteArray(object Value)
        {
            if (Value == DBNull.Value) return new byte[0];
            else return Value;
        }
        #endregion

        #region bool AvoidNullBool(object Value)
        public static bool AvoidNullBool(object Value)
        {
            if (Value == DBNull.Value) return false;
            else return (bool)Value;
        }
        #endregion

        #region int AvoidNullint(object Value)
        public static int AvoidNullint(object Value)
        {
            if (Value == DBNull.Value) return 0;
            else return int.Parse(Value.ToString());
        }
        #endregion

        public static int? AvoidNullIntNullable(object Value)
        {
            if (Value == DBNull.Value) return null;
            else return ConvertToIntNullable(Value.ToString());
        }

        public static byte AvoidNullByte(object Value)
        {
            if (Value == DBNull.Value) return 0;
            else return ConvertToByte(Value.ToString());
        }

        public static byte? AvoidNullByteNullable(object Value)
        {
            if (Value == DBNull.Value) return null;
            else return ConvertToByteNullable(Value.ToString());
        }

        public static short AvoidNullShort(object Value)
        {
            if (Value == DBNull.Value) return 0;
            else return ConvertToByte(Value.ToString());
        }

        public static short? AvoidNullShortNullable(object Value)
        {
            if (Value == DBNull.Value) return null;
            else return ConvertToShortNullable(Value.ToString());
        }

        #region static decimal AvoidNullDecimal(object Value)
        public static decimal AvoidNullDecimal(object Value)
        {
            if (Value == DBNull.Value) return 0;
            else return decimal.Parse(Value.ToString());
        }
        #endregion

        #region static decimal? AvoidNullDecimalNullable(object Value)
        public static decimal? AvoidNullDecimalNullable(object Value)
        {
            if (Value == DBNull.Value) return null;
            else return ConvertToDecimalNullable(Value.ToString());
        }
        #endregion

        #region Single AvoidNullSingle(object Value)
        public static Single AvoidNullSingle(object Value)
        {
            if (Value == DBNull.Value) return 0;
            else return Single.Parse(Value.ToString());
        }
        #endregion

        #region Single AvoidNullSingleCurrency(object Value)
        public static Single AvoidNullSingleCurrency(object Value)
        {
            if (Value == DBNull.Value) return 0;
            else
            {
                Single s = Single.Parse(Value.ToString());
                return Single.Parse(s.ToString("#,###.00"));

            }
        }
        #endregion

        #region double AvoidNulldouble(object Value)
        public static double AvoidNulldouble(object Value)
        {
            if (Value == DBNull.Value) return 0;
            else return double.Parse(Value.ToString());
        }
        #endregion

        #region DateTime AvoidNullDateTime(object objValue)
        public static DateTime AvoidNullDateTime(object objValue)
        {
            if (objValue == DBNull.Value)
            {
                DateTime dateTime = new DateTime();
                dateTime = DateTime.MinValue;
                return dateTime;

            }
            else return (DateTime)objValue;
        }
        #endregion

        #region DateTime? AvoidNullDateTime(object objValue)
        public static DateTime? AvoidNullDateTimeNullable(object objValue)
        {
            if (objValue == DBNull.Value)
            {
                return null;
            }
            else return (DateTime)objValue;
        }
        #endregion

        #region string TextOf(bool Value)
        public static string TextOf(bool Value)
        {
            if (Value)
                return "Yes";
            else
                return "No";
        }
        #endregion

        #region object GetDBNull(DateTime Value)
        public static object GetDBNull(DateTime Value)
        {
            if (Value == SetMinimumdate()) return DBNull.Value;
            else return Value;

        }

        #endregion

        #region object GetDBNull(DateTime? Value)
        public static object GetDBNull(DateTime? Value)
        {
            if (Value == null) return DBNull.Value;
            else return Value;

        }

        #endregion

        #region int ConvertToInt(string value)
        public static int ConvertToInt(string value)
        {
            int i = 0;
            int.TryParse(value, out i);

            return i;
        }
        #endregion

        #region int? ConvertToIntNullable(string value)
        public static int? ConvertToIntNullable(string value)
        {
            if (value == null || value == "")
            {
                return null;
            }
            else
            {
                return ConvertToInt(value);
            }
        }
        #endregion



        #region int? ConvertToIntNullableZeroNull(string value)
        public static int? ConvertToIntNullableZeroNull(string value)
        {
            if (value == null || value == "" || value == "0")
            {
                return null;
            }
            else
            {
                return ConvertToInt(value);
            }
        }
        #endregion


        #region long ConvertToLong(string value)
        public static long ConvertToLong(string value)
        {
            long i = 0;
            long.TryParse(value, out i);

            return i;
        }
        #endregion

        #region long? ConvertToLongNullable(string value)
        public static long? ConvertToLongNullable(string value)
        {
            if (value == null || value == "")
            {
                return null;
            }
            else
            {
                return ConvertToLong(value);
            }
        }
        #endregion



        #region long? ConvertToLongNullableZeroNull(string value)
        public static long? ConvertToLongNullableZeroNull(string value)
        {
            if (value == null || value == "" || value == "0")
            {
                return null;
            }
            else
            {
                return ConvertToLong(value);
            }
        }
        #endregion





        public static byte ConvertToByte(string value)
        {
            byte i = 0;
            byte.TryParse(value, out i);
            return i;
        }

        #region byte? ConvertToByteNullable(string value)
        public static byte? ConvertToByteNullable(string value)
        {
            if (value == null || value == "")
            {
                return null;
            }
            else
            {
                return ConvertToByte(value);
            }
        }
        #endregion

        #region byte? ConvertToByteNullableZeroNull(string value)
        public static byte? ConvertToByteNullableZeroNull(string value)
        {
            if (value == null || value == "" || value == "0")
            {
                return null;
            }
            else
            {
                return ConvertToByte(value);
            }
        }
        #endregion


        public static short ConvertToShort(string value)
        {
            short i = 0;
            short.TryParse(value, out i);
            return i;
        }

        public static decimal ConvertToDecimal(string value)
        {
            decimal i = 0;
            decimal.TryParse(value, out i);
            return i;
        }

        #region short? ConvertToShortNullable(string value)
        public static short? ConvertToShortNullable(string value)
        {
            if (value == null || value == "")
            {
                return null;
            }
            else
            {
                return ConvertToShort(value);
            }
        }
        #endregion

        #region decimal? ConvertToDecimalNullable(string value)
        public static decimal? ConvertToDecimalNullable(string value)
        {
            if (value == null || value == "")
            {
                return null;
            }
            else
            {
                return ConvertToDecimal(value);
            }
        }
        #endregion

        #region short? ConvertToShortNullableZeroNull(string value)
        public static short? ConvertToShortNullableZeroNull(string value)
        {
            if (value == null || value == "" || value == "0")
            {
                return null;
            }
            else
            {
                return ConvertToShort(value);
            }
        }
        #endregion

        #region DateTime? AvoidNullDateTimeNullable(string value)
        public static DateTime? AvoidNullDateTimeNullable(string value)
        {
            if (value == null || value == "")
            {
                return null;
            }
            else return DateTime.Parse(value);
        }
        #endregion

        #endregion

        #region Converters
        /// <summary>
        /// Will be validate providded input for perdefined regex patterns
        /// </summary>
        /// <param name="value">Parameter type of string to validate regex pattern</param>
        /// <param name="type">Predefined regx validation types</param>
        /// <returns>Boolean</returns>
        /// <exception cref="System.Exception">Generic Exception</exception>
        public static bool ValidatePattern(string param, RegXPatterns pattern)
        {
            if (!string.IsNullOrEmpty(param))
            {
                bool isValid = false;
                switch (pattern)
                {
                    case RegXPatterns.IsIPAddress:
                        isValid = validatePattern(param, REGX_IP_ADDRESS);
                        break;
                    case RegXPatterns.IsEmailAddress:
                        isValid = validatePattern(param, REGX_EMAIL);
                        break;
                    case RegXPatterns.IsURL:
                        isValid = validatePattern(param, REGX_URL);
                        break;
                    case RegXPatterns.IsNumbers:
                        isValid = validatePattern(param, REGX_NUMBERS);
                        break;
                    case RegXPatterns.IsAlphaNumberic:
                        isValid = validatePattern(param, REGX_ALPHANUMERIC);
                        break;
                    case RegXPatterns.IsUSAZip:
                        isValid = validatePattern(param, REGX_ZIP_USA);
                        break;
                    case RegXPatterns.IsUSAPhoneNumber:
                        isValid = validatePattern(param, REGX_PHONE_USA);
                        break;
                    case RegXPatterns.IsUSASSNumber:
                        isValid = validatePattern(param, REGX_SSN_USA);
                        break;
                    case RegXPatterns.IsUSACreditCardNumber:
                        isValid = validatePattern(param, REGX_CREDIT_CARD);
                        break;
                    case RegXPatterns.IsAlphabet_azAZ:
                        isValid = validatePattern(param, REGX_ALPHABET_FROMAT_1);
                        break;
                    case RegXPatterns.IsAlphabet_AZaz:
                        isValid = validatePattern(param, REGX_ALPHABET_FROMAT_2);
                        break;
                    case RegXPatterns.IsDateTime_DDMMYY:
                        isValid = validatePattern(param, REGX_DATE_DDMMYY);
                        break;
                    case RegXPatterns.IsDateTime_DDMMYYYMH:
                        isValid = validatePattern(param, REGX_DATE_DDMMYYYY_TIME);
                        break;
                    case RegXPatterns.IsDateTime_DDMMYYYY:
                        isValid = validatePattern(param, REGX_DATE_DDMMYYYY);
                        break;
                    case RegXPatterns.IsDateTime_MMDDYY:
                        isValid = validatePattern(param, REGX_DATE_MMDDYY);
                        break;
                    case RegXPatterns.IsDateTime_MMDDYYYMH:
                        isValid = validatePattern(param, REGX_DATE_MMDDYYYY_TIME);
                        break;
                    case RegXPatterns.IsDateTime_MMDDYYYY:
                        isValid = validatePattern(param, REGX_DATE_MMDDYYYY);
                        break;
                }
                return isValid;
            }
            else
                return false;
        }

        /// <summary>
        /// Will convert custom/predefine enumerater to a defined type
        /// </summary>
        /// <typeparam name="T">Type of enumerater</typeparam>
        /// <param name="comaprer">String value to compare</param>
        /// <param name="ignoreCase">Determaine the to ignore case</param>
        /// <returns>Converted type or default type if failed</returns>
        public static T ConvertEnum<T>(string comaprer, bool ignoreCase)
        {
            try
            {
                return (T)Enum.Parse(typeof(T), comaprer, ignoreCase);
            }
            catch 
            { }
            return default(T);
        }

        /// <summary>
        /// Will convert object to define primitive type
        /// </summary>
        /// <typeparam name="T">Data type to be converted</typeparam>
        /// <param name="value">Parameter</param>
        /// <returns>Converted type or default type if failed</returns>
        public static T ConvertAny<T>(object param)
        {
            T local = default(T);
            Type temp = typeof(T);
            try
            {
                if (temp.IsGenericType && temp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                {
                    NullableConverter converter = new NullableConverter(temp);
                    temp = converter.UnderlyingType;

                    if (param != null)
                        local = (T)Convert.ChangeType(param, temp);
                    return local;
                }
                else if ((param != null)
                          && (IsNumber(param.ToString())))
                    local = (T)Convert.ChangeType(param, typeof(T));
            }
            catch 
            { }
            return local;
        }

        #endregion

        #endregion

        #region Private Method
        private object ChangeType(object value, Type conversionType)
        {
            if (conversionType == null)
                throw new ArgumentNullException("conversionType");
            if (conversionType.IsGenericType
                && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                if (value == null)
                    return null;
                NullableConverter converter = new NullableConverter(conversionType);
                conversionType = converter.UnderlyingType;
            }
            return Convert.ChangeType(value, conversionType);
        }

        private static bool IsNumber(string param)
        {
            double num;
            return double.TryParse(param, NumberStyles.Float, (IFormatProvider)NumberFormatInfo.CurrentInfo, out num);
        }

        private static bool validatePattern(string value, string pattern)
        {
            return Regex.IsMatch(value, pattern);
        }

        #endregion

        #region Private Regex Constants
        /// <summary>
        /// Zip code must be 5 numeric digits, USA
        /// </summary>
        public const string REGX_ZIP_USA = @"^\d{5}$";
        /// <summary>
        /// Phone number validation USA
        /// </summary>
        /// <example>(555) 555-5555</value>
        /// <example>555.555.5555</example>
        /// <example>555 555-5555</example>
        public const string REGX_PHONE_USA = @"^\(?\s*\d{3}\s*[\)\.\-]?\s*\d{3}\s*[\-\.]?\s*\d{4}$";
        /// <summary>
        /// Social security number of USA
        /// </summary>
        /// <example>555-33-2222</example>
        public const string REGX_SSN_USA = @"^\d{3}-\d{2}-\d{4}$";
        /// <summary>
        /// Credit card validation
        /// </summary>
        /// <example>1111-2222-3333-4444</example>
        public const string REGX_CREDIT_CARD = @"^\d{4}-\d{4}-\d{4}-\d{4}$";
        /// <summary>
        /// Ip Address
        /// </summary>
        /// <example>192.168.150.252</example>
        public const string REGX_IP_ADDRESS = @" ^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$";
        /// <summary>
        /// Email 
        /// </summary>
        /// <example>saravanan@yahoo.com|net|org|edu|int|mil|gov|arpa|biz|
        /// aero|name|coop|info|pro|museum</example>
        public const string REGX_EMAIL = @"^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$";
        /// <summary>
        /// URL validation
        /// </summary>
        /// <example> http://www.yahoo.com|net|org|edu|int|mil
        /// |gov|arpa|biz|aero|name|coop|info|pro|museum</example>
        public const string REGX_URL = @"http://(www\.)?([^\.]+)\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$";
        /// <summary>
        /// A-Z or a-z Alphabets only allowed
        /// </summary>
        public const string REGX_ALPHABET_FROMAT_1 = @"^[a-zA-Z]+$";
        /// <summary>
        /// A-Z or a-z Alphabets only allowed
        /// </summary>
        /// <example>a to z</example>
        /// <example>A to Z</example>
        public const string REGX_ALPHABET_FROMAT_2 = @"^[A-Za-z]+$";
        /// <summary>
        /// Numbers only allowed
        /// </summary>
        /// <example>0 to 9</example>
        public const string REGX_NUMBERS = @"^[0-9]+$";
        /// <summary>
        /// Alphanumeric values
        /// </summary>
        /// <example>A2233B</example>
        public const string REGX_ALPHANUMERIC = @"^\w+$";
        /// <summary>
        /// Date Time Validation (dd-mm-yyyy:HM)
        /// </summary>
        /// <example>22-03-1980:12.30 </example>
        /// <example>22.03.1980:12.30 </example>
        /// <example>22/03/1980:12.30 </example>
        public const string REGX_DATE_DDMMYYYY_TIME = @"^((0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](?:19|20)\d\d)$";
        /// <summary>
        /// Date Time Validation (mm-dd-yyyy:HM)
        /// </summary>
        /// <example>03-22-1980:12.30 </example>
        /// <example>03.22.1980:12.30 </example>
        /// <example>03/22/1980:12.30 </example>
        public const string REGX_DATE_MMDDYYYY_TIME = @"^((0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\d\d)$";
        /// <summary>
        /// Date Time Validation (mm-dd-yyyy)
        /// </summary>
        /// <example>03-22-1980 </example>
        /// <example>03.22.1980 </example>
        /// <example>03/22/1980 </example>
        public const string REGX_DATE_MMDDYYYY = @"^([1-9]|0[1-9]|1[012])[- /.]([1-9]|0[1-9]|[12][0-9]|3[01])[- /.][0-9]{4}$";
        /// <summary>
        /// Date Time Validation (dd-mm-yyyy)
        /// </summary>
        /// <example>23-12-1980 </example>
        /// <example>23.12.1980 </example>
        /// <example>23/12/1980 </example>
        public const string REGX_DATE_DDMMYYYY = @"^([1-9]|0[1-9]|[12][0-9]|3[01])[- /.]([1-9]|0[1-9]|1[012])[- /.][0-9]{4}$";
        /// <summary>
        /// Date Time Validation (mm-dd-yy)
        /// </summary>
        /// <example>03-22-80 </example>
        /// <example>03.22.80 </example>
        /// <example>03/22/80 </example>
        public const string REGX_DATE_MMDDYY = @"^([1-9]|0[1-9]|1[012])[- /.]([1-9]|0[1-9]|[12][0-9]|3[01])[- /.][0-9]{2}$";
        /// <summary>
        /// Date Time Validation (dd-mm-yy)
        /// </summary>
        /// <example>23-12-80 </example>
        /// <example>23.12.80 </example>
        /// <example>23/12/80 </example>
        public const string REGX_DATE_DDMMYY = @"^([1-9]|0[1-9]|[12][0-9]|3[01])[- /.]([1-9]|0[1-9]|1[012])[- /.][0-9]{2}$";
        #endregion
    }
}
